package com.zzyd.common.weight.lines;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.zzyd.common.helper.utils.Dp2Px;

import java.text.SimpleDateFormat;
import java.util.Date;


/**
 * @author wjunjie
 * @version 1.0
 * @E-mail wang_junjie007@163.com
 * @company ZZYD
 * @createTime 2018/7/27 16:46
 * @类注释: 初级 K 线
 */
public class KlineOne extends View {

    private Paint mPaint;
    /**
     * view 高
     */
    private int vHeight;
    /**
     * view 宽
     */
    private int vWidth;
    /**
     * 文字宽度
     */
    private int txtWidth;
    /**
     * 文字大小
     */
    private int txtSize;
    /**
     * 价格
     */
    private double[] yPoints;
    private long[] xTimes;
    private double maxPrice;
    private double minPrice;
    private double ySpacingPrice;
    /**
     * 数据是否有问题
     */
    private boolean isErrorData = false;

    /**
     * X 坐标点间距
     */
    private double xSpacing;
    /**
     * Y 坐标点间距
     */
    private double ySpacing;
    /**
     * 底部文本高度
     */
    private double buttomTxtHeigth;

    private int padding;

    public KlineOne(Context context) {
        super(context);
        init();
    }

    public KlineOne(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public KlineOne(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        int heigth = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, heigth);
    }

    /**
     * 初始化
     */
    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
    }

    /**
     * 初始化数据
     */
    private void initdata() {
        vWidth = getWidth();
        vHeight = getHeight();
        txtWidth = Dp2Px.dip2px(getContext(), 50);
        txtSize = Dp2Px.dip2px(getContext(), 10);
        padding = Dp2Px.dip2px(getContext(), 10);
        buttomTxtHeigth = Dp2Px.dip2px(getContext(), 22);

        ySpacing = (vHeight - padding - buttomTxtHeigth) / 3;

        ySpacingPrice = (maxPrice - minPrice) / 4;
        if (yPoints == null || yPoints.length < 2) {
            return;
        }
        xSpacing = (vWidth - txtWidth - 2 * padding) / (yPoints.length - 1);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        initdata();
        drawDashed(canvas);
        drawPrice(canvas);
        drawKlines(canvas);
        drawTime(canvas);
    }

    /**
     * 价格文字
     */
    private void drawPrice(Canvas canvas) {
        Paint paint = mPaint;
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.GRAY);
        if (yPoints == null || yPoints.length < 3 || isErrorData) {
            paint.setStrokeWidth(4);
            paint.setTextSize(Dp2Px.dip2px(getContext(), 16));
            paint.setTextAlign(Paint.Align.CENTER);
            canvas.drawText("暂无数据", vWidth / 2, vHeight / 2, paint);
            return;
        }
        if (maxPrice > minPrice) {
            paint.setStrokeWidth(2);
            paint.setTextSize(Dp2Px.dip2px(getContext(), 9));
            canvas.drawText(Double.toString(maxPrice), padding, padding + 9, paint);
            canvas.drawText(Double.toString(maxPrice + 2 * ySpacingPrice), padding, (float) (9 + padding + ySpacing), paint);
            canvas.drawText(Double.toString(minPrice + ySpacingPrice), padding, (float) (9 + padding + 2 * ySpacing), paint);
            canvas.drawText(Double.toString(minPrice), padding, (float) (9 + padding + 3 * ySpacing), paint);
        }
    }

    /**
     * 虚线
     */
    private void drawDashed(Canvas canvas) {
        Paint paint = mPaint;
        paint.setColor(Color.GRAY);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        paint.setPathEffect(new DashPathEffect(new float[]{6, 4}, 0));
        Path path = new Path();

        // 四条虚线路径
        for (int i = 0; i < 4; i++) {
            path.moveTo(txtWidth + padding, (float) (i * ySpacing + padding));
            path.lineTo(vWidth - padding, (float) (i * ySpacing + padding));
        }
        canvas.drawPath(path, paint);
    }

    /**
     * 折线
     */
    private void drawKlines(Canvas canvas) {
        if (yPoints == null) {
            return;
        }
        Paint paint = mPaint;
        paint.reset();
        paint.setColor(Color.RED);
        paint.setStrokeWidth((float) 2.5);
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);
        Path path = new Path();
        for (int i = 0; i < yPoints.length; i++) {
            if (i == 0) {
                path.moveTo(getX(i), getY(i));
            }
            path.lineTo(getX(i), getY(i));
        }
        canvas.drawPath(path, paint);
    }

    /**
     * 底部时间
     */
    private void drawTime(Canvas canvas) {
        if (xTimes == null || xTimes.length == 0) {
            return;
        }
        SimpleDateFormat format = new SimpleDateFormat("MM-dd~HH:mm");
        Date date1 = new Date(xTimes[1]);
        String time1 = format.format(date1);
        Date date2 = new Date(xTimes[xTimes.length - 1]);
        String time2 = format.format(date2);

        Paint paint = mPaint;
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.GRAY);
        paint.setStrokeWidth(2);
        paint.setTextSize(Dp2Px.dip2px(getContext(), 10));
        canvas.drawText(time1, padding + txtWidth, vHeight - 12, paint);
        if (xTimes.length > 4) {
            int i = xTimes.length / 4;
            int i1 = (vWidth - padding - txtWidth) / 4;
            Date date3 = new Date(xTimes[i]);
            String time3 = format.format(date3);
            Date date4 = new Date(xTimes[2 * i]);
            String time4 = format.format(date4);
            canvas.drawText(time3, 2 * padding + txtWidth + i1, vHeight - 9, paint);
            canvas.drawText(time4, 2 * padding + txtWidth + 2 * i1, vHeight - 9, paint);
        }
        paint.setTextAlign(Paint.Align.RIGHT);
        canvas.drawText(time2, vWidth - padding, vHeight - 9, paint);
    }

    /**
     * y坐标点
     *
     * @param position position
     * @return Y
     */
    private float getY(int position) {
        double yPoint = yPoints[position];
        return (float) (((vHeight - padding - buttomTxtHeigth) * (1 - (yPoint - minPrice) / (maxPrice - minPrice))) + padding);
    }

    /**
     * x坐标点
     *
     * @param position position
     * @return X
     */
    private float getX(int position) {
        return (float) ((xSpacing * position) + txtWidth + padding);
    }

    /**
     * 外部赋值
     *
     * @param dates 价格
     * @return this
     */
    public KlineOne setDate(double[] dates) {
        if (dates != null) {
            yPoints = dates;
        }
        setMaxMin(getMaxPrice(dates), getMinPrice(dates));
        return this;
    }

    /**
     * 外部赋值
     *
     * @param times 时间
     * @return
     */
    public KlineOne setTimes(long[] times) {
        if (times != null) {
            this.xTimes = times;
        }
        return this;
    }

    /**
     * 设置最大 最小值
     *
     * @param maxPrice Max
     * @param minPrice Min
     * @return this
     */
    public KlineOne setMaxMin(double maxPrice, double minPrice) {
        this.maxPrice = maxPrice;
        this.minPrice = minPrice;
        if (maxPrice == minPrice) {
            isErrorData = true;
        } else {
            isErrorData = false;
        }
        return this;
    }

    /**
     * 最大值
     *
     * @param dates
     * @return
     */
    private double getMaxPrice(double[] dates) {
        if (dates == null || dates.length == 0) {
            return 0;
        }
        double a = dates[0];
        for (int i = 0; i < dates.length; i++) {
            if (dates[i] >= a) {
                a = dates[i];
            }
        }
        return a;
    }

    /**
     * 最小值
     *
     * @param dates
     * @return
     */
    private double getMinPrice(double[] dates) {
        if (dates == null || dates.length == 0) {
            return 0;
        }
        double a = dates[0];
        for (int i = 0; i < dates.length; i++) {
            if (dates[i] <= a) {
                a = dates[i];
            }
        }
        return a;
    }

}
